#ifndef INPUTGESTUREDRAG_H_INCLUDED
#define INPUTGESTUREDRAG_H_INCLUDED

#include "InputGestureBasicFingers.h"

#include <map>

namespace tuio

{

class ditdrag
{
    public:
    float tstamp;
    float x,y;
    float velx, vely;
};

class TeventNewDrag : public TTEvent <TeventNewDrag>
{
    public:
    float x,y;
    float velx, vely;
    bool  b_removed;
};


class InputGestureDrag : public CanBasicFingers< tuioApp <InputGesture> >
{
    public:
    InputGestureBasicFingers * gesturefingers;
    std::map<int,ditdrag *> elsdits;
    int id_1,id_2,num_fingers;
    float xpre,ypre;

    InputGestureDrag()
    {
        gesturefingers = Singleton<InputGestureBasicFingers>::get();num_fingers=0;
    }

    virtual void ReceiveCall(const char * addr, osc::ReceivedMessageArgumentStream & argList)
    {
        std::list<TEvent*>::iterator it;
        for(it = gesturefingers->events.begin();
            it != gesturefingers->events.end();
            it++)
        {
            TEvent * e = *it;
            processTevent(e);
        }
    }

    //Interface redefined by ofApp
    void addTuioCursor(int32 id, float xpos,float ypos,float xspeed,float yspeed,float maccel)
    {
        ditdrag * d = new ditdrag();
        d->tstamp = ofGetElapsedTimef();
        d->x = xpos;
        d->y = ypos;

        elsdits[id] = d;

        if(num_fingers == 0)
        {
            id_1 = id;
            num_fingers++;
            xpre =xpos;
            ypre= ypos;
        }
    }
    void updateTuioCursor(int32 id, float xpos,float ypos,float xspeed,float yspeed,float maccel)
    {
        if (num_fingers==1)
        {
            if (id_1==id)
            {
                TeventNewDrag * evt = new TeventNewDrag();
                evt->x = xpos;
                evt->y = ypos;
                evt->velx = (xpos-xpre);
                evt->vely = (ypos-ypre);
                evt->b_removed=false;
                events.push_back(evt);
                xpre=xpos;
                ypre=ypos;
                elsdits[id]->velx=(xpos-xpre);
                elsdits[id]->x=xpos;
                elsdits[id]->y=ypos;
            }

        }

   }
    void removeTuioCursor(int32 id)
    {
        if (id_1==id)
        {
            TeventNewDrag * evt = new TeventNewDrag();
            evt->velx = elsdits[id]->velx;//we update the event with the last value;
            evt->x = elsdits[id]->x;
            evt->y = elsdits[id]->y;
            evt->b_removed = true;
            events.push_back(evt);
            id_1 = 0;
            num_fingers--;
        }
    }

};

template<class Base>
class CanDrag : public Base
{
    public:
  ///Interficie
  virtual void newDrag(double x,double y, float speedx, bool removed){}

  ///Handlers
  TEventHandler(TeventNewDrag)
  {
      TeventNewDrag * e = static_cast<TeventNewDrag *>(evt);
      newDrag(e->x,e->y, e->velx, e->b_removed);
  }

  ///Register
  CanDrag()
  {
      TRegistraCallback(CanDrag,TeventNewDrag);
      registerMeToInputGestureManager(Singleton<InputGestureDrag>::get());
  }

    eventprocessorsType & getEP()
    {
        return Base::getEP();
    }

};

}


#endif // INPUTGESTUREDRAG_H_INCLUDED
